/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MyDataContainer;

import java.util.ArrayList;
import MyDataType.*;
import MyCondition.*;
/**
 *
 * @author Welcome
 */
public class MyQuery {
    //<editor-fold defaultstate="collapsed" desc="1/ Các thuộc tính cơ bản">
    protected MyDataString columnTitles;
    protected MyDataString dataTypeList;
    protected ArrayList<MyDataSet> rowContents;
    protected String name;
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="2/ Các phương thức khởi tạo">
    public MyQuery() {
        this.columnTitles = new MyDataString();
        this.dataTypeList = new MyDataString();
        this.rowContents = new ArrayList<MyDataSet>();
        name="";
    }
    
    public MyQuery(MyDataString columnTitles, MyDataString dataTypeList, ArrayList<MyDataSet> rowContents,String name)
    {
        this.columnTitles = new MyDataString(columnTitles);
        this.dataTypeList = new MyDataString(dataTypeList);
        this.rowContents = new ArrayList<MyDataSet>(rowContents);
        this.name=name;
    }
    
    public MyQuery(MyQuery myQuery)
    {
        this.columnTitles = new MyDataString(myQuery.columnTitles);
        this.dataTypeList = new MyDataString(myQuery.dataTypeList);
        this.rowContents = new ArrayList<MyDataSet>(myQuery.rowContents);
        this.name=myQuery.name;
    }
    
    public MyQuery(MyTable myTable)
    {
        this.name = myTable.name;
        this.columnTitles = new MyDataString(myTable.getColumnTitles());
        this.rowContents = new ArrayList<MyDataSet>(myTable.rowContents);
        this.dataTypeList = new MyDataString(myTable.dataTypeList);
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="3/ Các phương thức Get/Set">
    public MyDataString getColumnTitles() {
        return columnTitles;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public void setColumnTitles(MyDataString columnTitles) {
        this.columnTitles = columnTitles;
    }
    
    public MyDataString getDataTypeList() {
        return dataTypeList;
    }
    
    public void setDataTypeList(MyDataString dataTypeList) {
        this.dataTypeList = dataTypeList;
    }
    
    public ArrayList<MyDataSet> getRowContents() {
        return rowContents;
    }
    
    public void setRowContents(ArrayList<MyDataSet> rowContents) {
        this.rowContents = rowContents;
    }
    
    public int getSize()
    {
        return rowContents.size();
    }
    
    /**
     * Get DataSet theo row
     * @param index-vị trí row
     * @return row data
     */
    public MyDataSet getRowAt(int index)
    {
        return rowContents.get(index);
    }
    
    public MyDataSet getColumnAt(int index)
    {
        MyDataSet result = new MyDataSet();
        for(int i=0; i<rowContents.size();i++)
        {
            MyDataSet tempDataSet=rowContents.get(index);
            MyData tempData = tempDataSet.getDataAt(index);
            result.addData(tempData);
        }
        
        return result;
    }
    
    public void addContent(MyDataSet rowData)
    {
        rowContents.add(rowData);
    }
    
    public MyDataSet getColumnAt(String columnName)
    {
        int pos = columnTitles.getPosition(columnName);
        return getColumnAt(pos);
    }
    //</editor-fold>
    
    //<editor-fold defaultstate="collapsed" desc="4/ Các phương thức xử lý nghiệp vụ">
    public MyQuery filterSelect(MyDataString selectFields)
    {
        MyQuery result = new MyQuery();
        result.setColumnTitles(selectFields);
        result.setName("filtedQuery");
        //position lưu vị trí các field sẽ lấy ra
        int[] position=new int[selectFields.getSize()];
        //Xac dinh vi tri cac cot can lay
        for(int i=0; i<selectFields.getSize();i++)
        {
            String temp = selectFields.getAt(i);
            position[i]=getColumnTitles().getPosition(temp);
        }
        
        //Xác định kiểu dữ liệu
        MyDataString dataType=new MyDataString();
        for(int i=0;i<position.length;i++)
        {
            dataType.addContent(this.getDataTypeList().getAt(position[i]));
        }
        result.setDataTypeList(dataType);
        
        //Lọc dữ liệu ở các cột lưu trong position rồi đưa vào resultTable
        
        for(int i=0;i<rowContents.size();i++)
        {
            MyDataSet rowData = new MyDataSet();
            for(int j=0;j<position.length;j++)
            {
                rowData.setData(rowContents.get(i).getDataAt(position[j]));
            }
            
            result.addContent(rowData);
        }
        
        return result;
    }
    
    public void clearAll()
    {
        rowContents.clear();
    }
    
    public MyQuery innerJoinerQuery(MyQuery myQuery,MyForeignKey foreignKey)
    {
        MyQuery resultQuery = new MyQuery();
        resultQuery.setName("innerJoinQuery");
        
        //set new column titles
        MyDataString newColumnTitle = new MyDataString();
        for(int i=0;i<columnTitles.getSize();i++)
        {
            newColumnTitle.addContent(name+"."+columnTitles.getAt(i));
        }
        for(int i=0;i<myQuery.getColumnTitles().getSize();i++)
        {
            newColumnTitle.addContent(myQuery.getName()+"."+myQuery.getColumnTitles().getAt(i));
        }
        resultQuery.setColumnTitles(newColumnTitle);
        
        //Set new dataType
        MyDataString dataType = new MyDataString(dataTypeList);
        dataType.addContent(new MyDataString(myQuery.getDataTypeList()));
        resultQuery.setDataTypeList(dataType);
        
        //Vi tri cot thu 1 trong foreign key
        String hostField = foreignKey.getHostField();
        int hostfieldPos = getColumnTitles().getPosition(hostField);

        //Vi tri cot thu 2 trong foreign key
        String desField = foreignKey.getDesField();
        int desfieldPos = myQuery.getColumnTitles().getPosition(desField);
        
        ArrayList<MyDataSet> rowContents1=rowContents;
        ArrayList<MyDataSet> rowContents2=myQuery.getRowContents();
        
        for(int i=0;i<rowContents1.size();i++)
            {
                for(int j=0;j<rowContents2.size();j++)
                {
                    //MyData rowData = rowContents1.get(i));
                    MyDataSet rowData1 = new MyDataSet(rowContents1.get(i));
                    MyDataSet rowData2 = new MyDataSet(rowContents2.get(j));
                    //Dieu kien loc du lieu o day
                    MyData leftSide = rowData1.getDataAt(hostfieldPos);
                    MyData rightSide = rowData2.getDataAt(desfieldPos);
                    String sign ="=";
                    boolean temp = leftSide.comparisonWith(rightSide, sign);

                    if(temp)
                    {
                        rowData1.addData(rowData2);
                        resultQuery.addContent(rowData1);
                    }
                }

            }
        
        return resultQuery;
    }

    public static MyQuery fullOuterJoinQuery(ArrayList<MyQuery> myQuerys)
    {
        MyQuery resultQuery = new MyQuery();
        resultQuery.setName("fullOuterJoinQuery");
        
        //set new infomation
        MyDataString newColumnTitle = new MyDataString();
        MyDataString newDateType = new MyDataString();
        ArrayList<MyDataSet> newRowContent=new ArrayList<MyDataSet>();
        
        for(int i=0; i<myQuerys.size();i++)
        {
            //Lay ra 1 query
            MyQuery tempQuery = new MyQuery(myQuerys.get(i));
            MyDataSet temDataSet = new MyDataSet();
            
            newRowContent=joinTwoDataSetList(newRowContent,tempQuery.getRowContents());
            newDateType.addContent(new MyDataString(tempQuery.getDataTypeList()));
            
            for(int j=0; j<tempQuery.getColumnTitles().getSize();j++)
            {
                newColumnTitle.addContent(tempQuery.getName()+"."+tempQuery.getColumnTitles().getAt(j));
            }
            
        }
        resultQuery.setColumnTitles(newColumnTitle);
        resultQuery.setDataTypeList(newDateType);
        resultQuery.setRowContents(newRowContent);
        return resultQuery;
    }
    
    public static ArrayList<MyDataSet> joinTwoDataSetList(ArrayList<MyDataSet> set1,ArrayList<MyDataSet> set2)
    {
     
        ArrayList<MyDataSet> result = new ArrayList<MyDataSet>();
        if(set1.size()==0)
            result.addAll(set2);
        
        for(int i=0;i<set1.size();i++)
            {
                for(int j=0;j<set2.size();j++)
                {
                    //MyData rowData = rowContents1.get(i));
                    MyDataSet rowData = new MyDataSet(set1.get(i));
                    rowData.addData(set2.get(j));
                    result.add(rowData);
                }

            }
        
        return result;
    }
    
    public String getDataTypeOfColumn(String columnName) {
        int position = columnTitles.getPosition(columnName);
        String kind = dataTypeList.getAt(position);
        return kind;
    }
    public String getDataTypeOfColumn(int columnNumber)
    {
        String kind = dataTypeList.getAt(columnNumber);
        return kind;
    }
    
    public void showData()
    {
        System.out.println(this.name);
        columnTitles.showData();
        dataTypeList.showData();
        
        for(int i=0; i<rowContents.size();i++)
        {
            rowContents.get(i).showData();
            System.out.println();
        }
        
    }
    
    public MyQuery filterCondition(String condition) {
        MyQuery resultQuery = new MyQuery();
        
        MyCondition myCondition = new MyCondition(condition);
        return resultQuery;
    }
    
    //</editor-fold>

    
}
